package com.fhyc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fhyc.dao.*;
import com.fhyc.dto.LoadCurveDto;
import com.fhyc.dto.LoadCurveShowDto;
import com.fhyc.entity.SoInLoadForecast;
import com.fhyc.entity.SoInLoadInfoTd;
import com.fhyc.entity.SoInLoadInfoXt;
import com.fhyc.entity.SoInTeam;
import com.fhyc.service.SoInLoadForecastService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 负荷预测表(SoInLoadForecast)表服务实现类
 *
 * @author makejava
 * @since 2024-10-10 16:58:30
 */
@Slf4j
@Service("soInLoadForecastService")
public class SoInLoadForecastServiceImpl extends ServiceImpl<SoInFhLoadForecastDao, SoInLoadForecast> implements SoInLoadForecastService {
    @Resource
    private SoInFhLoadForecastDao soInFhLoadForecastDao;

    @Resource
    private SoInTeamDao soInTeamDao;

    @Resource
    private SoInFhLoadInfoXtDao soInFhLoadInfoXtDao;

    @Resource
    private SoInFhLoadInfoTdDao soInFhLoadInfoTdDao;

    @Override
    public LoadCurveShowDto queryLoadForecastD1(String areaId, Integer loadTypeId, LocalDate localDate, List<Integer> teamIds) {

/*        LocalDate tomorrowDate = localDate.plusDays(1);
        LambdaQueryWrapper<BuBusLoadEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(BuBusLoadEntity::getBusId, busId)
                .eq(BuBusLoadEntity::getTeamId, teamId)
                .and(i -> i.or().eq(BuBusLoadEntity::getDataDate, yesterdayDate).eq(BuBusLoadEntity::getDataType, 1)
                        .or().eq(BuBusLoadEntity::getDataDate, currentDate).eq(BuBusLoadEntity::getDataType, 1)
                        .or().eq(BuBusLoadEntity::getDataDate, tomorrowDate).eq(BuBusLoadEntity::getDataType, 2));
        List<BuBusLoadEntity> buBusLoadEntities = buBusLoadMapper.selectList(lqw);


        for (BuBusLoadEntity buBusLoadEntity : buBusLoadEntities) {
            curveList.add(
                    new LoadCurveDto(switchLocalDate(buBusLoadEntity.getDataDate(), currentDate), DataTypeEnum.ACTUAL, buBusLoadEntity.getValueList())
            );
        }*/
        // 定义日期格式化器
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将 LocalDateTime 格式化为 yyyy-MM-dd 格式的字符串
        String formattedDate = localDate.format(formatter2);
        //查询预测
        List<LoadCurveDto> curveList = new ArrayList<>();
        //List<Integer> ids = param.getTeamIds();
        //List<String> teamList = new ArrayList<>();
        for (Integer id : teamIds) {

            SoInTeam team = soInTeamDao.selectById(id);

            LoadCurveDto dto = new LoadCurveDto();
            List<Double> values = new ArrayList<>();
            dto.setName(team.getTeamName());

            QueryWrapper<SoInLoadForecast> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("qyid", areaId);
            queryWrapper.eq("yccj", team.getTeamName());
            queryWrapper.ge("ycrq", formattedDate + " " + "00:00:00");
            queryWrapper.le("ycrq", formattedDate + " " + "23:59:59");

            List<SoInLoadForecast> forecastList = soInFhLoadForecastDao.selectList(queryWrapper);
            for (SoInLoadForecast forecast : forecastList) {
                values.add(forecast.getYcz());
            }
            dto.setCurve(values);
            curveList.add(dto);
        }
        //实际值
        LocalDateTime now = LocalDateTime.now();
        LocalDate nowDate = LocalDate.now();
        System.out.println(nowDate);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 将LocalDateTime对象转换为String
        //String nowString = now.format(formatter);

        if (loadTypeId == 1) {
            //系统负荷
            if (localDate.isBefore(nowDate) || localDate.isEqual(nowDate)) {
                QueryWrapper<SoInLoadInfoXt> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("qyid", areaId);
                queryWrapper.ge("fhsj", formattedDate + " " + "00:00:00");
                queryWrapper.le("fhsj", formattedDate + " " + "23:59:59");

                List<SoInLoadInfoXt> loadInfos = soInFhLoadInfoXtDao.selectList(queryWrapper);
                LoadCurveDto dto = new LoadCurveDto();
                List<Double> values = new ArrayList<>();
                for (SoInLoadInfoXt loadInfo : loadInfos) {
                    values.add(loadInfo.getFh());
                }
                dto.setName("实际曲线");
                dto.setCurve(values);
                curveList.add(dto);

                //演示当天效果
                // 获取当前时间
                Calendar calendar = Calendar.getInstance();
                int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
                int currentMinute = calendar.get(Calendar.MINUTE);
                // 将小时和分钟转换为总分钟数
                int totalMinutes = currentHour * 60 + currentMinute;
                // 每15分钟一个点，计算总点数
                int totalPoints = (int) Math.ceil((double) totalMinutes / 15);
                //log.info("当天时间点：" + totalPoints);
                //List<LoadCurveDto> curveList
                LocalDate currentNow = LocalDate.now();
                if (localDate.equals(currentNow)) {
                    for (int i = totalPoints; i < 96; i++) {
                        List<Double> curve = dto.getCurve();
                        if (!CollectionUtils.isEmpty(curve)) {
                            curve.set(i, null);
                        }
                    }
                }
            }
        } else if (loadTypeId == 2) {
            //统调负荷
            if (localDate.isBefore(nowDate) || localDate.isEqual(nowDate)) {
                QueryWrapper<SoInLoadInfoTd> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("qyid", areaId);
                queryWrapper.ge("fhsj", formattedDate + " " + "00:00:00");
                queryWrapper.le("fhsj", formattedDate + " " + "23:59:59");

                List<SoInLoadInfoTd> loadInfos = soInFhLoadInfoTdDao.selectList(queryWrapper);
                LoadCurveDto dto = new LoadCurveDto();
                List<Double> values = new ArrayList<>();
                for (SoInLoadInfoTd loadInfo : loadInfos) {
                    values.add(loadInfo.getFh());
                }
                dto.setName("实际曲线");
                dto.setCurve(values);
                curveList.add(dto);

                //演示当天效果
                // 获取当前时间
                Calendar calendar = Calendar.getInstance();
                int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
                int currentMinute = calendar.get(Calendar.MINUTE);
                // 将小时和分钟转换为总分钟数
                int totalMinutes = currentHour * 60 + currentMinute;
                // 每15分钟一个点，计算总点数
                int totalPoints = (int) Math.ceil((double) totalMinutes / 15);
                //log.info("当天时间点：" + totalPoints);
                //List<LoadCurveDto> curveList
                LocalDate currentNow = LocalDate.now();
                if (localDate.equals(currentNow)) {
                    for (int i = totalPoints; i < 96; i++) {
                        List<Double> curve = dto.getCurve();
                        if (!CollectionUtils.isEmpty(curve)) {
                            curve.set(i, null);
                        }
                    }
                }
            }
        }

        LoadCurveShowDto loadCurveShowDto = new LoadCurveShowDto();
        //loadCurveShowDto.setCurveList(null);

        loadCurveShowDto.setCurveList(curveList);

        // 定义 DateTimeFormatter
        //DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 使用 Stream API 进行转换
        List<String> stringList = getTimeList1(localDate).stream()
                .map(localDateTime -> localDateTime.format(formatter)) // 格式化 LocalDateTime
                .collect(Collectors.toList()); // 收集结果到 List<String>
        loadCurveShowDto.setDateTime(stringList);
        return loadCurveShowDto;
    }

    @Override
    public LoadCurveShowDto queryLoadForecastD10(LocalDate startTime, LocalDate endTime, String areaId, Integer loadTypeId, List<Integer> teamIds) {
        /* LocalDate yesterdayDate = currentDate.minusDays(1);
        LocalDate tomorrowDate = currentDate.plusDays(1);
        LambdaQueryWrapper<BuBusLoadEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(BuBusLoadEntity::getBusId, busId)
                .eq(BuBusLoadEntity::getTeamId, teamId)
                .and(i -> i.or().eq(BuBusLoadEntity::getDataDate, yesterdayDate).eq(BuBusLoadEntity::getDataType, 1)
                        .or().eq(BuBusLoadEntity::getDataDate, currentDate).eq(BuBusLoadEntity::getDataType, 1)
                        .or().eq(BuBusLoadEntity::getDataDate, tomorrowDate).eq(BuBusLoadEntity::getDataType, 2));
        List<BuBusLoadEntity> buBusLoadEntities = buBusLoadMapper.selectList(lqw);

        List<LoadCurveDto> curveList = new ArrayList<>();
        for (BuBusLoadEntity buBusLoadEntity : buBusLoadEntities) {
            curveList.add(
                    new LoadCurveDto(switchLocalDate(buBusLoadEntity.getDataDate(), currentDate), DataTypeEnum.ACTUAL, buBusLoadEntity.getValueList())
            );
        }

*/

        // 定义日期格式化器
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将 LocalDateTime 格式化为 yyyy-MM-dd 格式的字符串
        String start = startTime.format(formatter2);
        String end = endTime.format(formatter2);
        LocalDateTime dateTime = LocalDateTime.now();
        LocalDate localDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 格式化时间并输出
        String now = dateTime.format(formatter);
        //查询预测
        List<LoadCurveDto> curveList = new ArrayList<>();
        //List<Integer> ids = param.getTeamIds();
        //List<String> teamList = new ArrayList<>();
        for (Integer id : teamIds) {

            SoInTeam team = soInTeamDao.selectById(id);

            LoadCurveDto dto = new LoadCurveDto();
            List<Double> values = new ArrayList<>();
            dto.setName(team.getTeamName());

            QueryWrapper<SoInLoadForecast> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("qyid", areaId);
            queryWrapper.eq("yccj", team.getTeamName());
            queryWrapper.ge("ycrq", start + " 00:00:00");
            queryWrapper.le("ycrq", end + " 23:59:59");

            List<SoInLoadForecast> forecastList = soInFhLoadForecastDao.selectList(queryWrapper);
            //去重
            values = forecastList.stream()
                    .collect(Collectors.collectingAndThen(
                            Collectors.toCollection(() ->
                                    new TreeSet<>(Comparator.comparing(f ->
                                            f.getYcrq() + "_" + f.getQyid() + "_" + f.getYccj()
                                    ))
                            ),
                            set -> set.stream().map(SoInLoadForecast::getYcz).collect(Collectors.toList())
                    ));
/*            for (SoInLoadForecast forecast : forecastList) {
                values.add(forecast.getYcz());
            }*/
            dto.setCurve(values);
            curveList.add(dto);
        }
        //实际值

        if (loadTypeId == 1) {
            //系统
            QueryWrapper<SoInLoadInfoXt> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("qyid", areaId);
            LoadCurveDto dto = new LoadCurveDto();
            List<Double> values = new ArrayList<>();
            // if ((startTime.isBefore(localDate) || startTime.equals(localDate))) {
            queryWrapper.ge("fhsj", start + " 00:00:00");
            queryWrapper.le("fhsj", end + " 23:59:59");
            List<SoInLoadInfoXt> loadInfos = soInFhLoadInfoXtDao.selectList(queryWrapper);
            //去重
            values = loadInfos.stream()
                    .collect(Collectors.collectingAndThen(
                            Collectors.toCollection(() ->
                                    new TreeSet<>(Comparator.comparing(f ->
                                            f.getFhsj() + "_" + f.getQyid()
                                    ))
                            ),
                            set -> set.stream().map(SoInLoadInfoXt::getFh).collect(Collectors.toList())
                    ));
/*            for (SoInLoadInfoXt loadInfo : loadInfos) {
                if (loadInfo.getFh() != null) {
                    values.add(loadInfo.getFh());
                }
            }*/
            dto.setName("实际曲线");
            dto.setCurve(values);
            curveList.add(dto);
            //     }
        } else if (loadTypeId == 2) {
            //统调
            QueryWrapper<SoInLoadInfoTd> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("qyid", areaId);
            LoadCurveDto dto = new LoadCurveDto();
            List<Double> values = new ArrayList<>();
            //       if ((startTime.isBefore(localDate) || startTime.equals(localDate))) {
            queryWrapper.ge("fhsj", start + " 00:00:00");
            queryWrapper.le("fhsj", end + " 23:59:59");
            List<SoInLoadInfoTd> loadInfos = soInFhLoadInfoTdDao.selectList(queryWrapper);
            //去重
            values = loadInfos.stream()
                    .collect(Collectors.collectingAndThen(
                            Collectors.toCollection(() ->
                                    new TreeSet<>(Comparator.comparing(f ->
                                            f.getFhsj() + "_" + f.getQyid()
                                    ))
                            ),
                            set -> set.stream().map(SoInLoadInfoTd::getFh).collect(Collectors.toList())
                    ));
/*            for (SoInLoadInfoTd loadInfo : loadInfos) {
                if (loadInfo.getFh() != null) {
                    values.add(loadInfo.getFh());
                }
            }*/
            dto.setName("实际曲线");
            dto.setCurve(values);
            curveList.add(dto);
            //       }
        }

        LoadCurveShowDto loadCurveShowDto = new LoadCurveShowDto();
        loadCurveShowDto.setCurveList(curveList);

       /* List<String> ycrqStrList = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        LocalDateTime startTime = LocalDateTime.parse(param.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endTime = LocalDateTime.parse(param.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        // 循环生成时间点
        LocalDateTime currentTime = startTime;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        while (currentTime.isBefore(endTime) || currentTime.equals(endTime)) {
            //System.out.println(currentTime.format(formatter));
            ycrqStrList.add(formatter.format(currentTime));
            currentTime = currentTime.plusMinutes(15);
        }*/


        // 定义 DateTimeFormatter
        // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 使用 Stream API 进行转换
        List<String> stringList = getTimeList10(startTime).stream()
                .map(localDateTime -> localDateTime.format(formatter)) // 格式化 LocalDateTime
                .collect(Collectors.toList()); // 收集结果到 List<String>
        loadCurveShowDto.setDateTime(stringList);
        return loadCurveShowDto;
    }

    // 获取时间数组
    private List<LocalDateTime> getTimeList1(LocalDate date) {
        List<LocalDateTime> timeList = new ArrayList<>();
        LocalDateTime start = date.atStartOfDay();
        for (LocalDateTime i = start; i.isBefore(start.plusDays(1)); i = i.plusMinutes(15)) {
            timeList.add(i);
        }
        return timeList;
    }

    private List<LocalDateTime> getTimeList10(LocalDate date) {
        List<LocalDateTime> timeList = new ArrayList<>();
        LocalDateTime start = date.atStartOfDay();
        for (LocalDateTime i = start; i.isBefore(start.plusDays(10)); i = i.plusMinutes(15)) {
            timeList.add(i);
        }
        return timeList;
    }


}
